/*******************************************************************/
/*
archivo: manejadorBits.cpp
*/
/*******************************************************************/

#include "StateControl.h"
#include <iostream>
//using namespace std;

StateControl::StateControl() {
	this->contadorUF = 0;
	this->contadorOV = 0;

}

StateControl::~StateControl() {
}

void StateControl::asignar() {

	int j=0;

	int i;

	for(i=31; i>=0; i--) {
		this->nPiso[i].b1= piso>>j;
		this->nTecho[i].b1= techo>>j;
		j++;
	}

}

void StateControl::setPiso(int piso) {
    this->piso = piso;
}

void StateControl::setTecho(int techo) {
    this->techo = techo;
}

int StateControl::getPiso()  {
    return this->piso;
}

int StateControl::getTecho() {
    return this->techo;
}

unsigned int StateControl::getContadorUF() {
	return contadorUF;
}

unsigned int StateControl::getContadorOV() {
	return contadorOV;
}

string StateControl::getEmision () {
	return emision;
}

void StateControl::agregarPisoFinal() {
	cout << endl;
	unsigned int i,j;

	empaquetado bit;

	this->asignar();


	this->controlOverflow();

	for (i=0; i<contadorOV; i++) {
		piso = (piso<<1) +0 ;
		techo = (techo<<1) +1;
	}

	bit.b1 = this->nPiso[0].b1;

	this->setPiso(piso);
	this->setTecho(techo);
	this->asignar();

	//this->almacenarSalida(bit);
	//cout << bit.b1;
	//this->controlUnderflow();

	if (contadorUF > 0) {
		for(j = 0; j < contadorUF; j++) {
			bit.b1 = ~this->nPiso[0].b1;
			this->almacenarSalida(bit);

		}
		contadorUF = 0;
	}

	for( i = 1 ; i < 32 - contadorOV ; i++) {

		bit.b1= this->nPiso[i].b1;

		this->almacenarSalida(bit);

	}

}

void StateControl::agregarPading() {
	char caracter;

	byte = (byte<<1) +1; // se agrega un 1 en el byte

	contadorCaracter++;

	if(contadorCaracter<8) {

		while (8-contadorCaracter > 0) {
			byte= byte << 1;	//se completa con ceros el byte
			contadorCaracter++;
		}
	}

	if(contadorCaracter == 8) {

		caracter = static_cast<char>(byte);

		emision = emision + caracter;

	}
}

void StateControl::mostrarVector(empaquetado vectorBits[32], string nombre) {

	int i;
	cout << nombre;

	for( i=0 ; i < 32 ;i++)
		cout << vectorBits[i].b1;

	cout << endl;

}

void StateControl::normalizar() {

	//mostrarBinario(this->piso,"pison");
	//mostrarBinario(this->techo,"techon");

	//cout<<"entro1"<<endl;
	this->controlOverflow();
	//cout<<"entro2"<<endl;
	this->controlUnderflow();

}

void StateControl::mostrarBinario(unsigned int binario, string nombre) {
	int j = 0;
	int i;

	empaquetado vectorBits[32];

	for ( i = 31 ; i>= 0 ; i--) {
		vectorBits[i].b1=binario>>j;
		j++;
	}

	for ( i = 0 ; i<32 ; i++) {
		cout<<vectorBits[i].b1;
			j++;
		}
	cout<<endl;

}

void StateControl::controlUnderflow () {


	int i;

	if ( (this->nPiso[0].b1==0) && (this->nTecho[0].b1==1) ) {
		//cout << "entro" << endl;

		if ((this->nPiso[1].b1==1) && (this->nTecho[1].b1==0)) {

			//cout << "entro2" << endl;
    		this->contadorUF++;
    		i=2;

    		while ( (this->nPiso[i].b1 == 1 ) && (this->nTecho[i].b1 == 0) && ( i< 30 ) ) {
    			this->contadorUF++;
    			i++;
    		}
    	}
    }

   }

void StateControl::controlOverflow() {

	bool iguales= true;
	int contador = 0;

	unsigned int i =0;
	unsigned int j;

	empaquetado bit;

	bit.b1= this->nTecho[0].b1;

	while ((iguales) && (i<32)) {
		if(this->nPiso[i].b1 == this->nTecho[i].b1) {

			if (this->contadorUF>0) {
				this->almacenarSalida(bit);

				unsigned int bitNegado = ~bit.b1;
				bit.b1= bitNegado;

				for (j=0;j<contadorUF;j++) {

					this->almacenarSalida(bit);


				}
				this->contadorUF = 0;

			}
			else{
				this->almacenarSalida(nTecho[i]);


			}

			contador++;
			i++;
		}
		else
			iguales = false;
	}

	this->contadorOV = contador;

}

void StateControl::almacenarSalida(empaquetado bit) {
	char caracter;


	if(contadorCaracter < 8) {
		byte = byte << 1;
		byte = byte + bit.b1;
		//cout << bit.b1;
		contadorCaracter++;
		//cout << "contadorCaracter " << contadorCaracter << endl;
	}

	if (contadorCaracter==8) {
		//cout << endl;
		caracter = static_cast<char>(byte);

		//cout << "caracter: " << caracter << " byte: " << byte << endl;
		emision = emision + caracter;
		contadorCaracter = 0;
	}
}
